package dk.mga.androidExplore.gpsTracker;

import java.util.ArrayList;
import java.util.Iterator;


import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class GPSLogService extends Service implements LocationListener {
	private final Binder binder = new GPSLogBinder();
	private String tag = "myLog";
	private ArrayList<LocationListener> listeners;
	private LocationManager lm;
	private Float odoMeter=0f;
	public final static String DELTA_DISTANCE = "DELTA_DIST";
	public final static String DISTANCE = "DISTANCE";
	
	 /**
	  * used as a flag and to store the string passed by the caller
	  * in LocationListener.onProviderDisabled(String arg0).
	  */
	private String providerDisabled;
	private boolean logInProgress=false;
	private Location latestLocation;

	@Override
	public IBinder onBind(Intent intent) {
		return binder;
	}
	
	/**
	 * My implementation of the IBinder interface.
	 * It is recommended to extend the Binder class
	 * rather than implement the IBinder interface.
	 * @author allan
	 *
	 */
	class GPSLogBinder extends Binder {
		GPSLogService getService() {
			return GPSLogService.this;
		}
	}
	
	void registerListener(LocationListener ll) {
		if (providerDisabled != null) { // make sure 'onProviderDisabled' is called in case GPS is disabled
			Log.d(tag, "onProviderDisabled called from GPSLogServise.registerListener()");
			ll.onProviderDisabled(providerDisabled);
		} else {
			ll.onProviderEnabled("gps");// Also make sure to call onProviderEnabled in that case
		}
		if (latestLocation != null) {
			ll.onLocationChanged(latestLocation);// provide listener with best/latest news
		}
		listeners.add(ll);
	}
	
	void unregisterListener(LocationListener ll) {
		if (listeners.contains(ll)) {
			listeners.remove(ll);
		}
	}

	/**
	 * Start logging sample data to database.
	 * @param dbHandler 
	 */
	void startLogging(LocationListener dbHandler) {
		Log.d(tag, "Logging is started");
		registerListener(dbHandler);
		logInProgress = true;
	}
	
	/**
	 * Stop logging to database
	 * @param dbHandler TODO
	 */
	void stopLogging(LocationListener dbHandler) {
		Log.d(tag, "Logging is stopped");
		unregisterListener(dbHandler);
		logInProgress = false;
	}
	
	/**
	 * @return true if logging is in progress.
	 */
	boolean isLogging() {
		return logInProgress;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		listeners = new ArrayList<LocationListener>();
		Log.d(tag, "GPSLogService on create");
		lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 10, this); // register as listener
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(tag, "GPSLogService on destroy");
		lm.removeUpdates(this); // unregister as listener
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		Log.d(tag, "GPSLogService On start id="+startId);
		return START_STICKY;// the service must remain running even if the client stops	
	}

	@Override
	public void onLocationChanged(Location loc) {
		Log.d(tag, "GPSLogService Location changed "+loc.toString());
		if (latestLocation == null) latestLocation = loc;
		Float delta = loc.distanceTo(latestLocation);
		odoMeter = odoMeter + delta;
		if (loc.getExtras() == null) {
			Bundle b = new Bundle();
			loc.setExtras(b);
		}
		loc.getExtras().putFloat(DELTA_DISTANCE, delta);// add delta distance
		loc.getExtras().putFloat(DISTANCE, odoMeter);// add trip meter distance
		Iterator<LocationListener> i = listeners.iterator();
		while (i.hasNext()) {
			i.next().onLocationChanged(loc);
		}
		latestLocation = loc;
	}

	@Override
	public void onProviderDisabled(String arg0) {
		Log.d(tag, arg0+" GPSLogService provider disabled");
		providerDisabled = arg0;

		Iterator<LocationListener> i = listeners.iterator();
		while (i.hasNext()) {
			i.next().onProviderDisabled(arg0);
		}
	}

	@Override
	public void onProviderEnabled(String arg0) {
		Log.d(tag, arg0+" GPSLogService provider enabled");
		providerDisabled = null;

		Iterator<LocationListener> i = listeners.iterator();
		while (i.hasNext()) {
			i.next().onProviderEnabled(arg0);
		}
	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		Log.d(tag, "GPSLogService Status changed "+arg0);

		Iterator<LocationListener> i = listeners.iterator();
		while (i.hasNext()) {
			i.next().onStatusChanged(arg0, arg1, arg2);
		}
	}

}
